#include "sorter.h"
#include "gtest/gtest.h"

class SorterTest : public ::testing::Test {

 protected:
  Sorter sorter_;
  wchar_t* test_input_file;
  wchar_t* test_output_file;
  char* test_input_file_char;
  char* test_output_file_char;

  virtual void SetUp() {
    test_input_file = L"test.txt";
    test_output_file = L"test_out.txt";
    test_input_file_char = "test.txt";;
    test_output_file_char = "test_out.txt";;
  }

  virtual void TearDown() {
    DeleteFile(test_input_file);
    DeleteFile(test_output_file);
  }
  
  void createFile(wchar_t* path) {
    // TODO: create file
  }

  void outputToFile(wchar_t* path, wchar_t* data) {
    // TODO: string output
  }

  void outputToFile(wchar_t* path, int* buffer) {
    // TODO: int output
  }

  int* getRandomBuffer(int size) {
    int* buffer = (int*)malloc(size * sizeof(int));
    for (int i = 0; i < size; i++) {
      buffer[i] = rand();
    }
    return buffer;
  }

  int* fileToIntArray(char* path) {
    // TODO: convert file to int array
    return 0;
  }
};

TEST_F(SorterTest, InvalidPathTest) {
  // Some invalid path
  char* invalid_path = "\\\%%%   ///";
  ASSERT_FALSE(sorter_.sort(invalid_path, invalid_path));
}

TEST_F(SorterTest, MissingSourceFileTest) {
  // Here must be a path to non-existing file
  char* non_existing_path = "C:/nonexisting.txt";
  char* valid_path = "C:/valid_file.txt";
  ASSERT_FALSE(sorter_.sort(non_existing_path, valid_path));
}

TEST_F(SorterTest, EmptySourceFileTest) {
  createFile(test_input_file);
  ASSERT_TRUE(sorter_.sort(test_input_file_char, test_output_file_char));
}

TEST_F(SorterTest, InvalidContentTest) {
  createFile(test_input_file);
  outputToFile(test_input_file, L"abc");
  ASSERT_NO_THROW(sorter_.sort(test_input_file_char, test_output_file_char));
}

TEST_F(SorterTest, CorrectSortTest) {
  createFile(test_input_file);
  int size = 100;
  int* buffer = getRandomBuffer(size);
  outputToFile(test_input_file, buffer);
  ASSERT_NO_THROW(ASSERT_TRUE(sorter_.sort(test_input_file_char, test_output_file_char)));
  int* result = fileToIntArray(test_output_file_char);
  // TODO: qsort
  int* sorted;
  for (int i = 0; i < size; i++) {
    EXPECT_EQ(sorted[i], result[i]);
  }
}

TEST_F(SorterTest, StressTest) {
  const DWORDLONG kSize = 10 * 1024 * 1024 * 1024;
  // TODO: complete stress test
}

int main(int argc, char* argv[]) {
  testing::InitGoogleTest(&argc, argv); 
  RUN_ALL_TESTS(); 
  std::getchar(); // keep console window open until Return keystroke
}
